<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>B站舞蹈区视频数据分析</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    <style>
        :root {
            --primary: #FFC300;
            --secondary: #A6F7E9;
            --info: #A6EAF7;
            --success: #A6BEF7;
            --warning: #F7A6E5;
            --danger: #F7A6B8;
            --distribution: #DAF7A6;
            --dance-gradient: linear-gradient(135deg, #FFC300, #F7A6B8, #A6EAF7);
        }

        body {
            background-color: #f8f9fa;
            background-image: linear-gradient(rgba(255, 255, 255, 0.95), rgba(245, 240, 250, 0.95)),
                              url('');
            background-size: 200px;
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
        }

        .header-wrapper {
            background: var(--dance-gradient);
            border-radius: 15px;
            padding: 15px 0;
            margin-bottom: 25px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
            position: relative;
            overflow: hidden;
        }

        .header-wrapper::before {
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M20,20 Q40,5 50,30 T80,20" fill="none" stroke="white" stroke-width="0.8" opacity="0.2"/><path d="M10,40 Q30,15 50,50 T90,40" fill="none" stroke="white" stroke-width="0.8" opacity="0.2"/></svg>');
            background-size: 200px;
            opacity: 0.2;
        }

        .dance-title {
            color: white;
            text-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
            position: relative;
            display: inline-block;
            font-weight: 700;
            letter-spacing: 1px;
        }

        .dance-title::after {
            content: "💃";
            position: absolute;
            right: -40px;
            top: -5px;
            animation: danceMove 3s infinite alternate;
            font-size: 35px;
        }

        @keyframes danceMove {
            0% { transform: rotate(0deg) scale(1); }
            25% { transform: rotate(15deg) scale(1.1); }
            50% { transform: rotate(0deg) scale(1); }
            75% { transform: rotate(-15deg) scale(1.1); }
            100% { transform: rotate(0deg) scale(1); }
        }

        .filter-section {
            background-color: white;
            border-radius: 12px;
            padding: 20px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
            margin-bottom: 25px;
            border-top: 4px solid var(--primary);
        }

        .filter-section label {
            font-weight: 600;
            color: #555;
            margin-bottom: 8px;
            display: block;
        }

        .btn-dance {
            background: var(--primary);
            border: none;
            font-weight: 600;
            transition: all 0.3s ease;
            color: #222;
            height: 46px;
            box-shadow: 0 4px 8px rgba(255, 195, 0, 0.3);
            position: relative;
            overflow: hidden;
        }

        .btn-dance::after {
            content: "";
            position: absolute;
            top: -50%;
            left: -50%;
            width: 200%;
            height: 200%;
            background: rgba(255, 255, 255, 0.3);
            transform: rotate(30deg);
            transition: all 0.6s ease;
        }

        .btn-dance:hover::after {
            transform: translateX(100%) rotate(30deg);
        }

        .btn-dance:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 12px rgba(255, 195, 0, 0.4);
            color: #222;
        }

        .btn-dance:active {
            transform: translateY(1px);
        }

        .nav-tabs .nav-link {
            border: none;
            border-bottom: 3px solid transparent;
            color: #666;
            font-weight: 600;
            padding: 12px 25px;
            transition: all 0.3s;
            position: relative;
            background: transparent;
        }

        .nav-tabs .nav-link.active {
            color: #e84393;
            border-bottom: 3px solid var(--warning);
            background: rgba(247, 166, 229, 0.1);
        }

        .nav-tabs .nav-link:hover:not(.active) {
            color: var(--danger);
            border-bottom: 3px solid rgba(247, 166, 184, 0.4);
        }

        .tab-content {
            padding: 20px;
            border-radius: 0 0 15px 15px;
            background-color: white;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
            border: none;
        }

        .chart-container {
            height: 500px;
            margin-bottom: 30px;
            background: white;
            border-radius: 10px;
            padding: 15px;
            box-shadow: 0 3px 10px rgba(0, 0, 0, 0.03);
        }

        .chart-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding: 0 10px;
        }

        .chart-header h3 {
            font-size: 18px;
            color: #e84393;
            margin: 0;
            font-weight: 700;
        }

        .stats-container {
            display: flex;
            gap: 20px;
        }

        .stat-card {
            background: linear-gradient(45deg, rgba(247, 166, 229, 0.15), rgba(166, 190, 247, 0.15));
            padding: 8px 15px;
            border-radius: 8px;
            text-align: center;
            min-width: 120px;
            border: 1px solid #e9ecef;
        }

        .stat-title {
            font-size: 12px;
            color: #6c757d;
            margin-bottom: 5px;
            text-transform: uppercase;
            font-weight: 600;
        }

        .stat-value {
            font-size: 16px;
            font-weight: 700;
            color: #e84393;
        }

        .ranking-table {
            font-size: 14px;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 3px 10px rgba(0, 0, 0, 0.03);
            max-height: 500px;
            overflow-y: auto;
        }

        .ranking-table th {
            position: sticky;
            top: 0;
            background: linear-gradient(to bottom, var(--success), var(--info));
            color: white;
            text-shadow: 0 1px 1px rgba(0,0,0,0.1);
            padding: 12px 8px;
        }

        .ranking-table tr:nth-child(odd) {
            background-color: rgba(166, 190, 247, 0.1);
        }

        .ranking-table tr:hover {
            background-color: rgba(247, 166, 229, 0.2);
            transform: translateX(3px);
            transition: all 0.2s ease;
        }

        .ranking-table td {
            padding: 12px 8px;
            border: none;
            border-bottom: 1px solid rgba(166, 230, 247, 0.2);
        }

        .ranking-table tr:first-child td {
            font-weight: bold;
            color: var(--danger);
            background-color: rgba(255, 215, 0, 0.1);
        }

        .ranking-table tr:nth-child(2) td {
            font-weight: bold;
            color: #e84393;
        }

        .ranking-table tr:nth-child(3) td {
            font-weight: bold;
            color: #00cec9;
        }

        .footer {
            margin-top: 30px;
            text-align: center;
            color: #888;
            font-size: 14px;
            padding: 15px;
        }

        .music-note {
            position: absolute;
            font-size: 18px;
            opacity: 0;
            color: var(--danger);
            animation: musicFloat 5s infinite linear;
        }

        @keyframes musicFloat {
            0% { transform: translateY(0) rotate(0deg); opacity: 0; }
            10% { opacity: 1; }
            90% { opacity: 1; }
            100% { transform: translateY(-100px) rotate(360deg); opacity: 0; }
        }

        .dance-badge {
            display: inline-block;
            background: linear-gradient(45deg, var(--primary), var(--danger));
            color: white;
            padding: 3px 12px;
            border-radius: 30px;
            font-size: 12px;
            margin-left: 10px;
            vertical-align: middle;
            font-weight: bold;
            animation: pulse 2s infinite;
        }

        @keyframes pulse {
            0% { box-shadow: 0 0 0 0 rgba(255, 195, 0, 0.7); }
            70% { box-shadow: 0 0 0 8px rgba(255, 195, 0, 0); }
            100% { box-shadow: 0 0 0 0 rgba(255, 195, 0, 0); }
        }

        .distribution-container {
            background-color: rgba(218, 247, 166, 0.15);
            border-radius: 12px;
            padding: 20px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
            margin-top: 25px;
        }

        .distribution-title {
            color: #e84393;
            text-align: center;
            margin-bottom: 20px;
            font-weight: 700;
            position: relative;
            display: inline-block;
            width: 100%;
        }

        .distribution-title::after {
            content: "";
            display: block;
            width: 100%;
            height: 4px;
            background: var(--distribution);
            margin-top: 8px;
            border-radius: 2px;
        }

        .time-distribution-chart {
            height: 400px;
        }
    </style>
</head>
<body>
    <div class="container-fluid py-4">
        <div class="header-wrapper">
            <div class="text-center">
                <h1 class="dance-title">B站舞蹈区视频数据分析</h1>
                <p class="text-white mb-0">探索舞蹈区优质内容与创作趋势 <span class="dance-badge">UP主必看</span></p>
            </div>
        </div>

        <!-- 数据筛选区域 -->
        <div class="filter-section">
            <div class="row">
                <div class="col-md-4">
                    <label for="minViews"><em class="fas fa-eye me-2"></em>最小播放量筛选</label>
                    <div class="input-group">
                        <input type="number" class="form-control" id="minViews" min="0" value="10000" placeholder="输入播放量阈值">
                        <span class="input-group-text">次</span>
                    </div>
                </div>
                <div class="col-md-4">
                    <label for="searchTitle"><em class="fas fa-search me-2"></em>标题关键词搜索</label>
                    <input type="text" class="form-control" id="searchTitle" placeholder="输入视频标题关键词">
                </div>
                <div class="col-md-4 d-flex align-items-end">
                    <button class="btn btn-dance w-100" id="applyFilter">
                        <em class="fas fa-filter me-2"></em>应用筛选
                    </button>
                </div>
            </div>
        </div>

        <!-- 选项卡导航 -->
        <ul class="nav nav-tabs" id="myTab" role="tablist">
            <li class="nav-item" role="presentation">
                <button class="nav-link active" id="likes-tab" data-bs-toggle="tab" data-bs-target="#likes" type="button" role="tab">
                    <em class="fas fa-thumbs-up me-2"></em>点赞率排行榜
                </button>
            </li>
            <li class="nav-item" role="presentation">
                <button class="nav-link" id="coins-tab" data-bs-toggle="tab" data-bs-target="#coins" type="button" role="tab">
                    <em class="fas fa-coins me-2"></em>投币率排行榜
                </button>
            </li>
            <li class="nav-item" role="presentation">
                <button class="nav-link" id="stars-tab" data-bs-toggle="tab" data-bs-target="#stars" type="button" role="tab">
                    <em class="fas fa-star me-2"></em>收藏率排行榜
                </button>
            </li>
            <li class="nav-item" role="presentation">
                <button class="nav-link" id="time-tab" data-bs-toggle="tab" data-bs-target="#time" type="button" role="tab">
                    <em class="fas fa-calendar-alt me-2"></em>发布时间分布
                </button>
            </li>
        </ul>

        <!-- 选项卡内容 -->
        <div class="tab-content" id="myTabContent">
            <!-- 点赞率 -->
            <div class="tab-pane fade show active" id="likes" role="tabpanel">
                <div class="row">
                    <div class="col-md-8">
                        <div class="chart-container">
                            <div class="chart-header">
                                <h3>点赞率排行榜 TOP 20</h3>
                                <div class="stats-container">
                                    <div class="stat-card">
                                        <div class="stat-title">平均值</div>
                                        <div class="stat-value" id="avgLikes">0.00%</div>
                                    </div>
                                    <div class="stat-card">
                                        <div class="stat-title">中位数</div>
                                        <div class="stat-value" id="medianLikes">0.00%</div>
                                    </div>
                                </div>
                            </div>
                            <canvas id="likesChart"></canvas>
                        </div>
                    </div>
                    <div class="col-md-4">
                        <div class="table-responsive">
                            <table class="table ranking-table">
                                 <caption class="sr-only">视频数据排行榜</caption>
                                <thead>
                                    <tr>
                                        <th scope="col">排名</th>
                                        <th scope="col">视频标题</th>
                                        <th scope="col">UP主</th>
                                        <th scope="col">点赞率</th>
                                    </tr>
                                </thead>
                                <tbody id="likesTable"></tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 投币率 -->
            <div class="tab-pane fade" id="coins" role="tabpanel">
                <div class="row">
                    <div class="col-md-8">
                        <div class="chart-container">
                            <div class="chart-header">
                                <h3>投币率排行榜 TOP 20</h3>
                                <div class="stats-container">
                                    <div class="stat-card">
                                        <div class="stat-title">平均值</div>
                                        <div class="stat-value" id="avgCoins">0.00%</div>
                                    </div>
                                    <div class="stat-card">
                                        <div class="stat-title">中位数</div>
                                        <div class="stat-value" id="medianCoins">0.00%</div>
                                    </div>
                                </div>
                            </div>
                            <canvas id="coinsChart"></canvas>
                        </div>
                    </div>
                    <div class="col-md-4">
                        <div class="table-responsive">
                            <table class="table ranking-table">
                                <caption class="sr-only">视频数据排行榜</caption>
                                <thead>
                                    <tr>
                                        <th scope="col">排名</th>
                                        <th scope="col">视频标题</th>
                                        <th scope="col">UP主</th>
                                        <th scope="col">投币率</th>
                                    </tr>
                                </thead>
                                <tbody id="coinsTable"></tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 收藏率 -->
            <div class="tab-pane fade" id="stars" role="tabpanel">
                <div class="row">
                    <div class="col-md-8">
                        <div class="chart-container">
                            <div class="chart-header">
                                <h3>收藏率排行榜 TOP 20</h3>
                                <div class="stats-container">
                                    <div class="stat-card">
                                        <div class="stat-title">平均值</div>
                                        <div class="stat-value" id="avgStars">0.00%</div>
                                    </div>
                                    <div class="stat-card">
                                        <div class="stat-title">中位数</div>
                                        <div class="stat-value" id="medianStars">0.00%</div>
                                    </div>
                                </div>
                            </div>
                            <canvas id="starsChart"></canvas>
                        </div>
                    </div>
                    <div class="col-md-4">
                        <div class="table-responsive">
                            <table class="table ranking-table">
                                <caption class="sr-only">视频数据排行榜</caption>
                                <thead>
                                    <tr>
                                        <th scope="col">排名</th>
                                        <th scope="col">视频标题</th>
                                        <th scope="col">UP主</th>
                                        <th scope="col">收藏率</th>
                                    </tr>
                                </thead>
                                <tbody id="starsTable"></tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 发布时间分布 -->
            <div class="tab-pane fade" id="time" role="tabpanel">
                <div class="distribution-container">
                    <h4 class="distribution-title">视频发布月度分布</h4>
                    <div class="time-distribution-chart">
                        <canvas id="timeChart"></canvas>
                    </div>
                </div>

                <div class="distribution-container mt-4">
                    <h4 class="distribution-title">一天内发布时间分布</h4>
                    <div class="time-distribution-chart">
                        <canvas id="hourlyChart"></canvas>
                    </div>
                </div>

                <div class="distribution-container mt-4">
                    <h4 class="distribution-title">一周内发布时间分布</h4>
                    <div class="time-distribution-chart">
                        <canvas id="weeklyChart"></canvas>
                    </div>
                </div>
            </div>
        </div>

        <div class="footer">
            <p><em class="fas fa-music me-2"></em>数据来源：Bilibili 舞蹈区 | 最新更新：2023年10月25日</p>
            <p class="small">让数据成为舞蹈创作的指南针！<em class="fas fa-heart mx-2" style="color: #e84393;"></em></p>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // 创建动态音符效果
        function createMusicNotes() {
            const notes = ['♫', '♪', '♩', '♬'];
            const container = document.querySelector('.container-fluid');

            for (let i = 0; i < 8; i++) {
                setTimeout(() => {
                    const note = document.createElement('div');
                    note.className = 'music-note';
                    note.textContent = notes[Math.floor(Math.random() * notes.length)];
                    note.style.left = Math.random() * 100 + 'vw';
                    note.style.animationDelay = Math.random() * 5 + 's';

                    container.appendChild(note);

                    // 动画结束后移除元素
                    setTimeout(() => {
                        note.remove();
                    }, 5000);
                }, i * 600);
            }
        }

        // 全局变量存储数据
        let originalData = [];
        let filteredData = [];

        // 加载JSON数据
        fetch('../static/dance.json')
            .then(response => response.json())
            .then(data => {
                originalData = data;
                // 计算互动率并添加新字段
                originalData.forEach(video => {
                    // 确保数值类型
                    video.views = parseInt(video.views) || 0;
                    video.likes = parseInt(video.likes) || 0;
                    video.coins = parseInt(video.coins) || 0;
                    video.stars = parseInt(video.stars) || 0;

                    // 计算互动率
                    video.likeRate = (video.views > 0) ? (video.likes / video.views * 100).toFixed(2) : 0;
                    video.coinRate = (video.views > 0) ? (video.coins / video.views * 100).toFixed(2) : 0;
                    video.starRate = (video.views > 0) ? (video.stars / video.views * 100).toFixed(2) : 0;

                    // 解析发布时间
                    if (video.pubdate_str) {
                        const dateParts = video.pubdate_str.split(' ')[0].split('-');
                        if (dateParts.length === 3) {
                            video.pubdate = new Date(`${dateParts[0]}-${dateParts[1]}-${dateParts[2]}`);
                            video.month = `${dateParts[0]}-${dateParts[1]}`;
                        }
                    }
                });
                applyFilters();
            })
            .catch(error => console.error('Error loading JSON data:', error));

        // 应用筛选条件
        function applyFilters() {
            const minViews = parseInt(document.getElementById('minViews').value) || 0;
            const searchKeyword = document.getElementById('searchTitle').value.toLowerCase();

            filteredData = originalData.filter(video => {
                return video.views >= minViews &&
                       video.title.toLowerCase().includes(searchKeyword);
            });

            renderAllCharts();
            renderTimeDistribution();
        }

        // 渲染所有图表
        function renderAllCharts() {
            renderRanking('likeRate', 'likesChart', 'likesTable', '点赞率排行榜', '点赞率(%)', '#FFC300', 'likes');
            renderRanking('coinRate', 'coinsChart', 'coinsTable', '投币率排行榜', '投币率(%)', '#A6F7E9', 'coins');
            renderRanking('starRate', 'starsChart', 'starsTable', '收藏率排行榜', '收藏率(%)', '#F7A6E5', 'stars');
        }

        // 渲染单个排行榜
        function renderRanking(rateField, chartId, tableId, chartTitle, rateLabel, color, type) {
            // 排序数据
            const sortedData = [...filteredData].sort((a, b) => b[rateField] - a[rateField]).slice(0, 20);

            // 计算统计信息
            const stats = calculateStats(filteredData, rateField);

            // 更新统计信息
            document.getElementById(`avg${type.charAt(0).toUpperCase() + type.slice(1)}`).textContent = `${stats.avg}%`;
            document.getElementById(`median${type.charAt(0).toUpperCase() + type.slice(1)}`).textContent = `${stats.median}%`;

            // 渲染表格
            const tableBody = document.getElementById(tableId);
            tableBody.innerHTML = '';

            sortedData.forEach((video, index) => {
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td>${index + 1}</td>
                    <td title="${video.title}">
                        <i class="fas fa-video me-2" style="color: ${color};"></i>
                        ${video.title.length > 15 ? video.title.substring(0, 15) + '...' : video.title}
                    </td>
                    <td>${video.up_name}</td>
                    <td><strong>${video[rateField]}%</strong></td>
                `;
                tableBody.appendChild(row);
            });

            // 渲染图表
            const ctx = document.getElementById(chartId).getContext('2d');

            // 销毁旧图表（如果存在）
            if (window[chartId + 'Instance']) {
                window[chartId + 'Instance'].destroy();
            }

            // 创建渐变色
            const gradient = ctx.createLinearGradient(0, 0, 0, 400);
            gradient.addColorStop(0, color);
            gradient.addColorStop(1, '#ffffff00');

            window[chartId + 'Instance'] = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: sortedData.map(video => video.title.length > 12 ? video.title.substring(0, 12) + '...' : video.title),
                    datasets: [{
                        label: rateLabel,
                        data: sortedData.map(video => parseFloat(video[rateField])),
                        backgroundColor: gradient,
                        borderColor: color,
                        borderWidth: 1.5,
                        borderRadius: 8,
                        hoverBackgroundColor: '#F7A6B8'
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            labels: {
                                font: {
                                    size: 14,
                                    family: "'Segoe UI', 'Microsoft YaHei', sans-serif"
                                },
                                color: '#555'
                            }
                        },
                        title: {
                            display: false,
                        },
                        tooltip: {
                            backgroundColor: 'rgba(255,255,255,0.95)',
                            titleColor: '#333',
                            bodyColor: '#555',
                            borderColor: '#ddd',
                            borderWidth: 1,
                            padding: 12,
                            displayColors: false,
                            callbacks: {
                                title: function(context) {
                                    const video = sortedData[context[0].dataIndex];
                                    return video.title;
                                },
                                label: function(context) {
                                    const video = sortedData[context.dataIndex];
                                    return [
                                        `UP主: ${video.up_name}`,
                                        `播放量: ${video.views.toLocaleString()}`,
                                        `点赞: ${video.likes.toLocaleString()}`,
                                        `投币: ${video.coins.toLocaleString()}`,
                                        `收藏: ${video.stars.toLocaleString()}`,
                                        `发布时间: ${video.pubdate_str}`
                                    ];
                                }
                            }
                        }
                    },
                    scales: {
                        y: {
                            beginAtZero: true,
                            title: {
                                display: true,
                                text: rateLabel,
                                font: {
                                    size: 14,
                                    weight: '600'
                                },
                                color: '#777'
                            },
                            grid: {
                                color: 'rgba(0,0,0,0.05)'
                            },
                            ticks: {
                                color: '#777'
                            }
                        },
                        x: {
                            grid: {
                                display: false
                            },
                            ticks: {
                                color: '#555',
                                font: {
                                    size: 12,
                                    family: "'Segoe UI', 'Microsoft YaHei', sans-serif"
                                },
                                maxRotation: 45,
                                minRotation: 45
                            }
                        }
                    },
                    animation: {
                        duration: 1000,
                        easing: 'easeOutQuart'
                    }
                }
            });
        }

        // 渲染时间分布图表
        function renderTimeDistribution() {
            // 1. 月度分布图
            const monthlyData = calculateMonthlyDistribution();
            renderMonthlyChart(monthlyData);

            // 2. 小时分布图
            const hourlyData = calculateHourlyDistribution();
            renderHourlyChart(hourlyData);

            // 3. 周分布图
            const weeklyData = calculateWeeklyDistribution();
            renderWeeklyChart(weeklyData);
        }

        // 计算月度分布数据
        function calculateMonthlyDistribution() {
            const monthCounts = {};

            filteredData.forEach(video => {
                if (video.month) {
                    if (!monthCounts[video.month]) {
                        monthCounts[video.month] = 0;
                    }
                    monthCounts[video.month]++;
                }
            });

            // 转换为数组并排序
            const months = Object.keys(monthCounts);
            months.sort();

            return {
                labels: months,
                data: months.map(month => monthCounts[month])
            };
        }

        // 计算小时分布数据
        function calculateHourlyDistribution() {
            const hourCounts = Array(24).fill(0);

            filteredData.forEach(video => {
                if (video.pubdate_str) {
                    const timePart = video.pubdate_str.split(' ')[1];
                    if (timePart) {
                        const hour = parseInt(timePart.split(':')[0]);
                        if (!isNaN(hour)) {
                            hourCounts[hour]++;
                        }
                    }
                }
            });

            return {
                labels: Array.from({length: 24}, (_, i) => `${i}:00`),
                data: hourCounts
            };
        }

        // 计算周分布数据
        function calculateWeeklyDistribution() {
            const dayCounts = Array(7).fill(0);
            const dayNames = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];

            filteredData.forEach(video => {
                if (video.pubdate) {
                    const day = video.pubdate.getDay(); // 0 = Sunday, 1 = Monday, etc.
                    dayCounts[day]++;
                }
            });

            // 重新排序为周一至周日
            const reorderedCounts = [...dayCounts.slice(1), dayCounts[0]];
            const reorderedLabels = dayNames.slice(1).concat(dayNames[0]);

            return {
                labels: reorderedLabels,
                data: reorderedCounts
            };
        }

        // 渲染月度分布图
        function renderMonthlyChart(monthlyData) {
            const ctx = document.getElementById('timeChart').getContext('2d');

            // 销毁旧图表（如果存在）
            if (window.timeChartInstance) {
                window.timeChartInstance.destroy();
            }

            // 创建渐变色
            const gradient = ctx.createLinearGradient(0, 0, 0, 400);
            gradient.addColorStop(0, '#DAF7A6');
            gradient.addColorStop(0.7, '#DAF7A6');
            gradient.addColorStop(1, '#ffffff00');

            window.timeChartInstance = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: monthlyData.labels,
                    datasets: [{
                        label: '每月视频数量',
                        data: monthlyData.data,
                        backgroundColor: gradient,
                        borderColor: '#9ECC7E',
                        borderWidth: 1.5,
                        borderRadius: 8,
                        hoverBackgroundColor: '#FFC300'
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            display: false
                        },
                        title: {
                            display: true,
                            text: '视频发布月度分布',
                            font: {
                                size: 16,
                                weight: 'bold'
                            },
                            padding: {
                                top: 10,
                                bottom: 20
                            }
                        },
                        tooltip: {
                            callbacks: {
                                title: function(tooltipItems) {
                                    return tooltipItems[0].label;
                                },
                                label: function(context) {
                                    return `视频数量: ${context.parsed.y}`;
                                }
                            }
                        }
                    },
                    scales: {
                        y: {
                            beginAtZero: true,
                            title: {
                                display: true,
                                text: '视频数量',
                                font: {
                                    size: 14,
                                    weight: '600'
                                },
                                color: '#777'
                            },
                            grid: {
                                color: 'rgba(0,0,0,0.05)'
                            }
                        },
                        x: {
                            title: {
                                display: true,
                                text: '月份',
                                font: {
                                    size: 14,
                                    weight: '600'
                                },
                                color: '#777'
                            },
                            grid: {
                                display: false
                            }
                        }
                    },
                    animation: {
                        duration: 1000,
                        easing: 'easeOutQuart'
                    }
                }
            });
        }

        // 渲染小时分布图
        function renderHourlyChart(hourlyData) {
            const ctx = document.getElementById('hourlyChart').getContext('2d');

            // 销毁旧图表（如果存在）
            if (window.hourlyChartInstance) {
                window.hourlyChartInstance.destroy();
            }

            // 创建渐变色
            const gradient = ctx.createLinearGradient(0, 0, 0, 300);
            gradient.addColorStop(0, '#DAF7A6');
            gradient.addColorStop(0.7, '#DAF7A6');
            gradient.addColorStop(1, '#ffffff00');

            window.hourlyChartInstance = new Chart(ctx, {
                type: 'line',
                data: {
                    labels: hourlyData.labels,
                    datasets: [{
                        label: '每小时发布数量',
                        data: hourlyData.data,
                        backgroundColor: gradient,
                        borderColor: '#9ECC7E',
                        borderWidth: 3,
                        pointBackgroundColor: '#FFC300',
                        pointBorderColor: '#fff',
                        pointHoverBackgroundColor: '#FF5733',
                        pointHoverBorderColor: '#fff',
                        pointRadius: 6,
                        pointHoverRadius: 8,
                        tension: 0.3,
                        fill: true
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            display: false
                        },
                        title: {
                            display: true,
                            text: '一天内发布时间分布',
                            font: {
                                size: 16,
                                weight: 'bold'
                            },
                            padding: {
                                top: 10,
                                bottom: 20
                            }
                        },
                        tooltip: {
                            callbacks: {
                                title: function(tooltipItems) {
                                    return `${tooltipItems[0].label}发布时段`;
                                },
                                label: function(context) {
                                    return `视频数量: ${context.parsed.y}`;
                                }
                            }
                        }
                    },
                    scales: {
                        y: {
                            beginAtZero: true,
                            title: {
                                display: true,
                                text: '视频数量',
                                font: {
                                    size: 14,
                                    weight: '600'
                                },
                                color: '#777'
                            },
                            grid: {
                                color: 'rgba(0,0,0,0.05)'
                            }
                        },
                        x: {
                            title: {
                                display: true,
                                text: '时间',
                                font: {
                                    size: 14,
                                    weight: '600'
                                },
                                color: '#777'
                            },
                            grid: {
                                display: false
                            }
                        }
                    },
                    animation: {
                        duration: 1000,
                        easing: 'easeOutQuart'
                    }
                }
            });
        }

        // 渲染周分布图
        function renderWeeklyChart(weeklyData) {
            const ctx = document.getElementById('weeklyChart').getContext('2d');

            // 销毁旧图表（如果存在）
            if (window.weeklyChartInstance) {
                window.weeklyChartInstance.destroy();
            }

            window.weeklyChartInstance = new Chart(ctx, {
                type: 'polarArea',
                data: {
                    labels: weeklyData.labels,
                    datasets: [{
                        label: '每周发布数量',
                        data: weeklyData.data,
                        backgroundColor: [
                            'rgba(218, 247, 166, 0.7)',
                            'rgba(255, 195, 0, 0.7)',
                            'rgba(166, 247, 233, 0.7)',
                            'rgba(166, 190, 247, 0.7)',
                            'rgba(247, 166, 229, 0.7)',
                            'rgba(247, 166, 184, 0.7)',
                            'rgba(166, 230, 247, 0.7)'
                        ],
                        borderColor: [
                            '#9ECC7E',
                            '#E6B800',
                            '#5BC0BE',
                            '#5B8CFF',
                            '#FF80AB',
                            '#FF6B6B',
                            '#4DC9E6'
                        ],
                        borderWidth: 1.5
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            position: 'right',
                            labels: {
                                font: {
                                    size: 12,
                                    family: "'Segoe UI', 'Microsoft YaHei', sans-serif"
                                },
                                padding: 15
                            }
                        },
                        title: {
                            display: true,
                            text: '一周内发布时间分布',
                            font: {
                                size: 16,
                                weight: 'bold'
                            },
                            padding: {
                                top: 10,
                                bottom: 20
                            }
                        },
                        tooltip: {
                            callbacks: {
                                label: function(context) {
                                    return `${context.label}: ${context.raw} 个视频`;
                                }
                            }
                        }
                    },
                    scales: {
                        r: {
                            pointLabels: {
                                display: false
                            },
                            ticks: {
                                display: false
                            }
                        }
                    },
                    animation: {
                        animateRotate: true,
                        animateScale: true,
                        duration: 1000
                    }
                }
            });
        }

        // 计算数据的统计信息
        function calculateStats(data, field) {
            const values = data.map(video => parseFloat(video[field])).filter(v => !isNaN(v));

            if (values.length === 0) {
                return { avg: 0, median: 0 };
            }

            // 计算平均值
            const avg = values.reduce((sum, val) => sum + val, 0) / values.length;

            // 计算中位数
            const sortedValues = [...values].sort((a, b) => a - b);
            const mid = Math.floor(sortedValues.length / 2);
            const median = sortedValues.length % 2 !== 0 ?
                sortedValues[mid] :
                (sortedValues[mid - 1] + sortedValues[mid]) / 2;

            return {
                avg: avg.toFixed(2),
                median: median.toFixed(2)
            };
        }

        // 绑定筛选按钮事件
        document.getElementById('applyFilter').addEventListener('click', applyFilters);

        // 页面加载完成后添加音乐动画效果
        document.addEventListener('DOMContentLoaded', function() {
            setInterval(createMusicNotes, 5000);
            createMusicNotes();
        });

        // 处理窗口调整大小
        window.addEventListener('resize', function() {
            // 重新渲染所有图表以适应新尺寸
            renderAllCharts();
            renderTimeDistribution();
        });
    </script>
</body>
</html>